package org.hb0712.sya.test.railwaydesign.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class RailwayAdjuster {
    private static final int MIN_DISTANCE = 1200;
    private static final int MAX_DISTANCE = 1500;

    public static void main(String[] args) {
        // 初始化测试数据
        List<Double> data = new ArrayList<>(Arrays.asList(0.0, 1300.0, 2600.0, 3900.0));
        
        // 测试用例
        testAdjustment(data, 2, 2800.0);  // 应当失败
        testAdjustment(data, 2, 2700.0);  // 应当成功
        testAdjustment(data, 2, 2400.0);  // 应当成功并自动调整前项
    }

    private static void testAdjustment(List<Double> original, int index, double newValue) {
        List<Double> copy = new ArrayList<>(original);
        System.out.println("尝试修改索引 " + index + " 的值 " + copy.get(index) + " -> " + newValue);
        
        if (tryAdjust(copy, index, newValue)) {
            System.out.println("修改成功，新序列：" + copy);
        } else {
            System.out.println("修改失败");
        }
        System.out.println("--------------------------");
    }

    public static boolean tryAdjust(List<Double> data, int index, double newValue) {
        if (index == 0 || index == data.size()-1) {
            System.out.println("首尾元素不可修改");
            return false;
        }

        double originalValue = data.get(index);
        data.set(index, newValue);

        // 向左传播调整
        if (!adjustLeft(data, index)) return rollback(data, index, originalValue);
        
        // 向右传播调整
        if (!adjustRight(data, index)) return rollback(data, index, originalValue);

        return true;
    }

    private static boolean adjustLeft(List<Double> data, int startIndex) {
        for (int i = startIndex; i > 0; i--) {
            double current = data.get(i);
            double prev = data.get(i-1);
            double diff = current - prev;

            if (diff < MIN_DISTANCE || diff > MAX_DISTANCE) {
                double newPrev = current - MAX_DISTANCE;  // 优先尝试最大间距
                if (newPrev < 0 || !validateLeftAdjustment(data, i-1, newPrev)) {
                    newPrev = current - MIN_DISTANCE;  // 再尝试最小间距
                    if (!validateLeftAdjustment(data, i-1, newPrev)) {
                        return false;
                    }
                }
                data.set(i-1, newPrev);
                System.out.println("自动调整索引 " + (i-1) + " 的值 -> " + newPrev);
            }
        }
        return true;
    }

    private static boolean validateLeftAdjustment(List<Double> data, int index, double newValue) {
        if (index > 0) {
            double prevDiff = newValue - data.get(index-1);
            if (prevDiff < MIN_DISTANCE || prevDiff > MAX_DISTANCE) return false;
        }
        return true;
    }

    private static boolean adjustRight(List<Double> data, int startIndex) {
        for (int i = startIndex; i < data.size()-1; i++) {
            double current = data.get(i);
            double next = data.get(i+1);
            double diff = next - current;

            if (diff < MIN_DISTANCE || diff > MAX_DISTANCE) {
                double newNext = current + MAX_DISTANCE;  // 优先尝试最大间距
                if (newNext > data.get(data.size()-1) || !validateRightAdjustment(data, i+1, newNext)) {
                    newNext = current + MIN_DISTANCE;  // 再尝试最小间距
                    if (!validateRightAdjustment(data, i+1, newNext)) {
                        return false;
                    }
                }
                data.set(i+1, newNext);
                System.out.println("自动调整索引 " + (i+1) + " 的值 -> " + newNext);
            }
        }
        return true;
    }

    private static boolean validateRightAdjustment(List<Double> data, int index, double newValue) {
        if (index < data.size()-1) {
            double nextDiff = data.get(index+1) - newValue;
            if (nextDiff < MIN_DISTANCE || nextDiff > MAX_DISTANCE) return false;
        }
        return true;
    }

    private static boolean rollback(List<Double> data, int index, double originalValue) {
        data.set(index, originalValue);
        return false;
    }
}
